#include "modelwindow.h"

#include "vx.h"
#include "vxmousetransmitter.h"
#include "vxlabel.h"
#include "vxscaletrigger.h"
#include "vxruller.h"
#include "vxdockcontainer.h"
#include "vxlabelscontainer.h"
#include "vxsymbolsexplorer.h"
#include "vxtextitem.h"

#include "vxfont.h"

ModelWindow::ModelWindow()
{

	_createWidgets();
}



void ModelWindow::setScale(int scale)
{
	QMatrix oldMatrix = view->matrix();
	view->resetMatrix();
	view->scale(scale, scale);
}



class TextLayoutItem : public QGraphicsItem
{

public:
	TextLayoutItem() : QGraphicsItem::QGraphicsItem()
	{

	}

	void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
	{
		QFont font("Verdana", 35);
		font.setStyleStrategy(QFont::ForceOutline);

		_layout = new QTextLayout("QWERTY", font);

		_layout->beginLayout();
		QTextLine line = _layout->createLine();
		_layout->endLayout();

		_layout->setText("QWERY");
		_layout->draw(painter, QPoint(0,0));
	}

	QRectF boundingRect() const
	{
		return QRectF(0, 0, 110, 70);
	}

private:
	QTextLayout * _layout;
};



void ModelWindow::_contentsChanged()
{
	connect(dtext, SIGNAL(lostFocus(VxTextItem*)), this, SLOT(_updateVectors()));
}


void ModelWindow::_updateVectors()
{
	disconnect(dtext, SIGNAL(lostFocus(VxTextItem*)), this, SLOT(_updateVectors()));
	delete _group;
	_group = new QGraphicsItemGroup();
	_group->setHandlesChildEvents(true);
	_group->setFlag(QGraphicsItem::ItemIsMovable, true);
	dtext->getOutLines(_group);
}

void ModelWindow::_above()
{
	_textScene->removeItem(dtext);
	_textScene->addItem(_group);
	_group->show();
}


void ModelWindow::_sunk()
{
	_textScene->addItem(dtext);
	_textScene->removeItem(_group);
	dtext->show();
}





VxDockCouple * _createDockCouple(QMainWindow * parent, Qt::DockWidgetArea area, Qt::DockWidgetAreas areas,
								 QString str, VxDockContainer * container, QDockWidget * dockwidget=0)
{

	QDockWidget * dockWidget;
	if (dockwidget == NULL){
		dockWidget = new QDockWidget(str, parent);
	} else {
		dockWidget = dockwidget;
	}

	dockWidget->setAllowedAreas(areas);

	parent->addDockWidget(area, dockWidget);

	dockWidget->setVisible(false);

	QPushButton * button = new QPushButton(container);
	button->setStyleSheet(
		"QPushButton {"
		"	border: 1px solid #8f8f91;"
		"	border-radius: 10px;"
		"	background-color: rgba(223, 224, 241, 100);"
		"	max-width: 40;"
		"	max-height: 40;"
		"}"
		"QPushButton:hover {"
		"	background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
		"									   stop: 0 #f6f7fa, stop: 1 #dadbde);"
		"}"
		"QPushButton:pressed {"
		"	background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
		"									   stop: 0 #dadbde, stop: 1 #f6f7fa);"
		"}");
	button->setText(str);

	return new VxDockCouple(button, dockWidget);

}

class TitleBar : public QWidget
{
public:
	TitleBar(QWidget * parent=0) : QWidget(parent)
	{

	}

	QSize minimumSizeHint() const
	{
		return QSize(20,20);
	}

	QSize sizeHint() const
	{
		return minimumSizeHint();
	}

};



class DockWidget : public QDockWidget
{
	Q_OBJECT

public:
	enum DockState{
		FloatingShifted,
		FloatingAccepted,
		Docked
	};

	DockWidget(QWidget * parent=0) : QDockWidget(parent)
	{
		connect(this, SIGNAL(visibilityChanged(bool)), this, SLOT(_visibilityChanged(bool)));

		connect(this, SIGNAL(floatingShifted()), this, SLOT(_floatingShifted()));
		connect(this, SIGNAL(floatingAccepted()), this, SLOT(_floatingAccepted()));
		connect(this, SIGNAL(docked()), this, SLOT(_docked()));
		_state = (isFloating()) ? FloatingAccepted : Docked;
	}

	bool event(QEvent *event)
	{
		switch(event->type()){
		case QEvent::MouseButtonRelease:{
				QTimer::singleShot(Vx::FloatingAcceptDelay, this, SLOT(_checkFloating()));
				break;
			}
		default:;
		}

		return QDockWidget::event(event);
	}


signals:
	void floatingShifted();
	void floatingAccepted();
	void docked();

private:
	DockState _state;

private slots:
	void _checkFloating()
	{
		if (_state == FloatingShifted && isFloating()){
			_state = FloatingAccepted;
			emit floatingAccepted();
		} else {
			_state = Docked;
		}

	}

	void _visibilityChanged(bool)
	{
		bool isfl = isFloating();
		if (!isfl && _state != Docked){
			_state = Docked;
			emit docked();
		} else
		if (isfl && _state == Docked){
			_state = FloatingShifted;
			emit floatingShifted();
		}
	}

	void _floatingShifted()
	{
	}

	void _floatingAccepted()
	{
	}

	void _docked()
	{
	}

};


class MultiProxyContainer : QObject
{
	Q_OBJECT
	
public:
	MultiProxyContainer(DockWidget * dockWidget, VxProxyWidget * proxyWidget, QWidget * contentWidget) :
			QObject(), _dockWidget(dockWidget), _proxyWidget(proxyWidget), _contentWidget(contentWidget)
	{
		connect(dockWidget, SIGNAL(floatingAccepted()), this, SLOT(_floatingAccepted()));
		connect(_proxyWidget, SIGNAL(breakdownEffort(QPoint)), this, SLOT(_proxyToDock(QPoint)));
	}

	void undock()
	{
		_floatingAccepted();
	}


private:
	DockWidget * _dockWidget;
	VxProxyWidget * _proxyWidget;
	QWidget * _contentWidget;

private slots:

	void _floatingAccepted()
	{
		_dockWidget->hide();
		QPoint gp = _dockWidget->mapToGlobal(QPoint(0,0));

		_contentWidget->setProperty("floating", true);

		_dockWidget->setTitleBarWidget(NULL);
		_contentWidget->setParent(NULL);

		_proxyWidget->setWidget(_contentWidget);

		_contentWidget->show();

		QPoint vp = _proxyWidget->getView()->mapFromGlobal(gp);
		_proxyWidget->setViewPos(vp);

		_proxyWidget->getView()->scene()->addItem(_proxyWidget);
		_proxyWidget->setZValue(0xfffff1);


	}

	void _proxyToDock(QPoint delta){
		if (!VxMouseTransmitter::instance()->pressed()){
			return;
		}
		_contentWidget->setProperty("floating", false);
		_contentWidget->setParent(NULL);
		_proxyWidget->cancelAnimation();
		_proxyWidget->setWidget(NULL);
		_dockWidget->setTitleBarWidget(_contentWidget);
		_dockWidget->move(_dockWidget->pos() + delta);
		_dockWidget->setFloating(false);
		_dockWidget->show();
		_contentWidget->show();
	}

};


void ModelWindow::_createWidgets()
{
	_textScene = new QGraphicsScene();

	_textScene->setSceneRect(QRectF(-2500, -2500, 5000, 5000));

	view = new VxGraphicsView(_textScene);


	view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
	view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

	setCentralWidget(view);


	dtext = new VxTextItem();
	dtext->loadExample();
	_textScene->addItem(dtext);
	_group = new QGraphicsItemGroup();
	_group->setFlag(QGraphicsItem::ItemIsSelectable, true);

	_updateVectors();


	connect(dtext->document(), SIGNAL(contentsChanged()), this, SLOT(_contentsChanged()));

	view->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

	VxScaleTrigger * trigger = new VxScaleTrigger(view->zoomController(), 6);
	connect(trigger, SIGNAL(above()), this, SLOT(_above()));
	connect(trigger, SIGNAL(sunk()), this, SLOT(_sunk()));

	//
	// Zoom
	//

	VxZoomSlider * zoomSlider = new VxZoomSlider(view->zoomController());

	DockWidget * dockZoom = new DockWidget();
	this->addDockWidget(Qt::LeftDockWidgetArea, dockZoom);

	dockZoom->setAllowedAreas(Qt::LeftDockWidgetArea |
								 Qt::RightDockWidgetArea);

	dockZoom->setFeatures(QDockWidget::DockWidgetClosable |
							 QDockWidget::DockWidgetMovable |
							 QDockWidget::DockWidgetFloatable);

	dockZoom->setWidget(new QWidget());
	dockZoom->widget()->setFixedHeight(1);
	dockZoom->widget()->setFixedWidth(zoomSlider->width());

	dockZoom->setTitleBarWidget(zoomSlider);

	VxProxyWidget * proxyZoom = new VxProxyWidget(view);
	MultiProxyContainer * multiZoom = new MultiProxyContainer(dockZoom, proxyZoom, zoomSlider);
	multiZoom->undock();
	proxyZoom->setViewPos(20,20);



	//
	// Informations
	//
	DockWidget * dockInformation = new DockWidget();
	this->addDockWidget(Qt::TopDockWidgetArea, dockInformation);

	dockInformation->setAllowedAreas(Qt::TopDockWidgetArea |
								 Qt::BottomDockWidgetArea);

	dockInformation->setFeatures(QDockWidget::DockWidgetClosable |
							 QDockWidget::DockWidgetMovable |
							 QDockWidget::DockWidgetFloatable);


	dockInformation->setWidget(new QWidget());
	dockInformation->widget()->setFixedWidth(1);


	VxLabelsContainer * labelsContainer = new VxLabelsContainer();
	dockInformation->setTitleBarWidget(labelsContainer);

	labelsContainer->addLabel(new VxLabelData("Font", "Verdana"), dockInformation);
	labelsContainer->addLabel(new VxLabelData("Name", "A"), dockInformation);
	labelsContainer->addLabel(new VxLabelData("Uni Nafghfghme", "LATIN A"), dockInformation);
	labelsContainer->addLabel(new VxLabelData("Uni code", "0041"), dockInformation);

	VxProxyWidget * proxyWidget = new VxProxyWidget(view);
	MultiProxyContainer * multic = new MultiProxyContainer(dockInformation, proxyWidget, labelsContainer);
	Q_UNUSED(multic);


	//
	// Symbols
	//

	DockWidget * dockSymbols = new DockWidget();
	this->addDockWidget(Qt::BottomDockWidgetArea, dockSymbols);

	dockSymbols->setAllowedAreas(Qt::TopDockWidgetArea |
								 Qt::BottomDockWidgetArea);

	dockSymbols->setFeatures(QDockWidget::NoDockWidgetFeatures);


	VxSymbolsExplorer * symbolsExplorer = new VxSymbolsExplorer();
	dockSymbols->setWidget(symbolsExplorer);
	dockSymbols->setTitleBarWidget(new QWidget());
	dockSymbols->titleBarWidget()->setFixedHeight(0);


	//
	// dock control
	//
	VxDockContainer * contentWidget = new VxDockContainer(view);

	contentWidget->addCouple(_createDockCouple(this, Qt::TopDockWidgetArea, Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea,
												QString("Information"), contentWidget));

	contentWidget->addCouple(_createDockCouple(this, Qt::LeftDockWidgetArea, Qt::AllDockWidgetAreas,
												QString("Symbols"), contentWidget));

	contentWidget->addCouple(_createDockCouple(this, Qt::LeftDockWidgetArea, Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea,
												QString("Gallery"), contentWidget));

	contentWidget->addCouple(_createDockCouple(this, Qt::LeftDockWidgetArea, Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea,
												QString("Objects"), contentWidget));

	contentWidget->addCouple(_createDockCouple(this, Qt::LeftDockWidgetArea, Qt::AllDockWidgetAreas,
												QString("Search"), contentWidget));



	contentWidget->addCouple(_createDockCouple(this, Qt::TopDockWidgetArea, Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea,
												QString("Metrics"), contentWidget));


	_ldock = new VxDockSelector(view, Qt::LeftDockWidgetArea, contentWidget);
	_rdock = new VxDockSelector(view, Qt::RightDockWidgetArea, contentWidget);
	_tdock = new VxDockSelector(view, Qt::TopDockWidgetArea, contentWidget);
	_bdock = new VxDockSelector(view, Qt::BottomDockWidgetArea, contentWidget);



	//
	//
	//
	_testFont();

	//
	//
	//

}



void ModelWindow::_testFont()
{
//	QFont * font = new QFont("Myriad Pro", 24);



}




#include "modelwindow.moc"
